/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.support.v4.view.accessibility;

import android.accessibilityservice.AccessibilityServiceInfo;
//import android.os.Build;
//import android.support.v4.view.accessibility.AccessibilityManagerCompatIcs.AccessibilityStateChangeListenerBridge;
import android.view.accessibility.AccessibilityManager;

import java.util.Collections;
import java.util.List;

/**
 * Helper for accessing features in {@link AccessibilityManager} introduced
 * after API level 4 in a backwards compatible fashion.
 */
public class AccessibilityManagerCompat {

	interface AccessibilityManagerVersionImpl {
		public Object newAccessiblityStateChangeListener(AccessibilityStateChangeListenerCompat listener);

		public boolean addAccessibilityStateChangeListener(AccessibilityManager manager, AccessibilityStateChangeListenerCompat listener);

		public boolean removeAccessibilityStateChangeListener(AccessibilityManager manager, AccessibilityStateChangeListenerCompat listener);

		public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(AccessibilityManager manager, int feedbackTypeFlags);

		public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(AccessibilityManager manager);

		public boolean isTouchExplorationEnabled(AccessibilityManager manager);
	}

	static class AccessibilityManagerStubImpl implements AccessibilityManagerVersionImpl {
		public Object newAccessiblityStateChangeListener(AccessibilityStateChangeListenerCompat listener) {
			return null;
		}

		public boolean addAccessibilityStateChangeListener(AccessibilityManager manager, AccessibilityStateChangeListenerCompat listener) {
			return false;
		}

		public boolean removeAccessibilityStateChangeListener(AccessibilityManager manager, AccessibilityStateChangeListenerCompat listener) {
			return false;
		}

		public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(AccessibilityManager manager, int feedbackTypeFlags) {
			return Collections.emptyList();
		}

		public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(AccessibilityManager manager) {
			return Collections.emptyList();
		}

		public boolean isTouchExplorationEnabled(AccessibilityManager manager) {
			return false;
		}
	}

	/*
	 * static class AccessibilityManagerIcsImpl extends
	 * AccessibilityManagerStubImpl {
	 * 
	 * @Override public Object newAccessiblityStateChangeListener( final
	 * AccessibilityStateChangeListenerCompat listener) { return
	 * AccessibilityManagerCompatIcs.newAccessibilityStateChangeListener( new
	 * AccessibilityStateChangeListenerBridge() { public void
	 * onAccessibilityStateChanged(boolean enabled) {
	 * listener.onAccessibilityStateChanged(enabled); } }); }
	 * 
	 * @Override public boolean
	 * addAccessibilityStateChangeListener(AccessibilityManager manager,
	 * AccessibilityStateChangeListenerCompat listener) { return
	 * AccessibilityManagerCompatIcs
	 * .addAccessibilityStateChangeListener(manager, listener.mListener); }
	 * 
	 * @Override public boolean
	 * removeAccessibilityStateChangeListener(AccessibilityManager manager,
	 * final AccessibilityStateChangeListenerCompat listener) { return
	 * AccessibilityManagerCompatIcs
	 * .removeAccessibilityStateChangeListener(manager, listener.mListener); }
	 * 
	 * @Override public List<AccessibilityServiceInfo>
	 * getEnabledAccessibilityServiceList( AccessibilityManager manager, int
	 * feedbackTypeFlags) { return
	 * AccessibilityManagerCompatIcs.getEnabledAccessibilityServiceList(manager,
	 * feedbackTypeFlags); }
	 * 
	 * @Override public List<AccessibilityServiceInfo>
	 * getInstalledAccessibilityServiceList( AccessibilityManager manager) {
	 * return
	 * AccessibilityManagerCompatIcs.getInstalledAccessibilityServiceList(
	 * manager); }
	 * 
	 * @Override public boolean isTouchExplorationEnabled(AccessibilityManager
	 * manager) { return
	 * AccessibilityManagerCompatIcs.isTouchExplorationEnabled(manager); } }
	 */
	static {
		// if (Build.VERSION.SDK_INT >= 14) { // ICS
		// IMPL = new AccessibilityManagerIcsImpl();
		// } else {
		IMPL = new AccessibilityManagerStubImpl();
		// }
	}

	private static final AccessibilityManagerVersionImpl IMPL;

	/**
	 * Registers an
	 * {@link AccessibilityManager.AccessibilityStateChangeListener} for changes
	 * in the global accessibility state of the system.
	 * 
	 * @param manager
	 *            The accessibility manager.
	 * @param listener
	 *            The listener.
	 * @return True if successfully registered.
	 */
	public static boolean addAccessibilityStateChangeListener(AccessibilityManager manager, AccessibilityStateChangeListenerCompat listener) {
		return IMPL.addAccessibilityStateChangeListener(manager, listener);
	}

	/**
	 * Unregisters an
	 * {@link AccessibilityManager.AccessibilityStateChangeListener}.
	 * 
	 * @param manager
	 *            The accessibility manager.
	 * @param listener
	 *            The listener.
	 * @return True if successfully unregistered.
	 */
	public static boolean removeAccessibilityStateChangeListener(AccessibilityManager manager, AccessibilityStateChangeListenerCompat listener) {
		return IMPL.removeAccessibilityStateChangeListener(manager, listener);
	}

	/**
	 * Returns the {@link AccessibilityServiceInfo}s of the installed
	 * accessibility services.
	 * 
	 * @param manager
	 *            The accessibility manager.
	 * @return An unmodifiable list with {@link AccessibilityServiceInfo}s.
	 */
	public static List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(AccessibilityManager manager) {
		return IMPL.getInstalledAccessibilityServiceList(manager);
	}

	/**
	 * Returns the {@link AccessibilityServiceInfo}s of the enabled
	 * accessibility services for a given feedback type.
	 * 
	 * @param manager
	 *            The accessibility manager.
	 * @param feedbackTypeFlags
	 *            The feedback type flags.
	 * @return An unmodifiable list with {@link AccessibilityServiceInfo}s.
	 * 
	 * @see AccessibilityServiceInfo#FEEDBACK_AUDIBLE
	 * @see AccessibilityServiceInfo#FEEDBACK_GENERIC
	 * @see AccessibilityServiceInfo#FEEDBACK_HAPTIC
	 * @see AccessibilityServiceInfo#FEEDBACK_SPOKEN
	 * @see AccessibilityServiceInfo#FEEDBACK_VISUAL
	 */
	public static List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(AccessibilityManager manager, int feedbackTypeFlags) {
		return IMPL.getEnabledAccessibilityServiceList(manager, feedbackTypeFlags);
	}

	/**
	 * Listener for the accessibility state.
	 */
	public static abstract class AccessibilityStateChangeListenerCompat {
		final Object mListener;

		public AccessibilityStateChangeListenerCompat() {
			mListener = IMPL.newAccessiblityStateChangeListener(this);
		}

		/**
		 * Called back on change in the accessibility state.
		 * 
		 * @param enabled
		 *            Whether accessibility is enabled.
		 */
		public abstract void onAccessibilityStateChanged(boolean enabled);
	}
}
